package com.lmj.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lmj.dto.DataRequest;
import com.lmj.dto.DataResponse;
import com.lmj.mapper.UserStatusMapper;
import com.lmj.pojo.CurDictionary;
import com.lmj.pojo.UserStatus;
import com.lmj.service.CurDictionaryService;
import com.lmj.service.UserStatusService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.BitFieldSubCommands;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UserStatusServiceImpl extends ServiceImpl<UserStatusMapper, UserStatus> implements UserStatusService {

    @Resource
    private UserStatusMapper userStatusMapper;

    // 响应体
    private DataResponse dataResponse;
    // 响应数据
    private Map<String, String> map = new HashMap<>();

    private static final String USER_SIGN_KEY = "User-Sign-";

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public DataResponse userSign(@RequestBody String request) {
        DataRequest requestBody = com.lmj.utils.RequestBody.getRequestBody(request);

        // 用户手机号
        String userPhone = requestBody.getString("userPhone");
        // 当前日期
        LocalDateTime now = LocalDateTime.now();
        // 键名后缀，如：:202311
        String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
        // 完整键名，如：User-Sign-17616204669:202311
        String key = USER_SIGN_KEY + userPhone + keySuffix;
        // 获取今天是本月的第几天，如：14
        int dayOfMonth = now.getDayOfMonth();
        // SETBIT key offset 1，说明：Redis偏移量从0开始计算
        redisTemplate.opsForValue().setBit(key, dayOfMonth - 1, true);

        map.clear();

        map.put("dayOfMonth", String.valueOf(dayOfMonth));

        return new DataResponse("200", map);
    }

    @Override
    public DataResponse getSignInfo(@RequestBody String request) {
        DataRequest requestBody = com.lmj.utils.RequestBody.getRequestBody(request);

        // 用户手机号
        String userPhone = requestBody.getString("userPhone");
        // 当前日期
        LocalDateTime now = LocalDateTime.now();
        // 键名后缀，如：:202311
        String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
        // 完整键名，如：User-Sign-17616204669:202311
        String key = USER_SIGN_KEY + userPhone + keySuffix;
        // 获取今天是本月的第几天，如：14
        int dayOfMonth = now.getDayOfMonth();
        // 获取从本月开始至今日的所有的签到记录，返回一个十进制的数组， BITFIELD User-Sign-10001:202311 GET u3 0
        List<Long> result = redisTemplate.opsForValue().bitField(
                key,
                BitFieldSubCommands.create()
                        .get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth)).valueAt(0));

        // 签到记录List
        List<Integer> SignInfo = new ArrayList<>();
        int whichDay = dayOfMonth;

        // 无签到记录
        if (result == null || result.isEmpty()) {
            map.clear();
            map.put("count", "0");
        } else {
            Long num = result.get(0);
            if (num == null || num == 0) {
                map.clear();
                map.put("count", "0");
            } else {
                int count = 0;
                while (whichDay != 0) {
                    // 让这个数字和1一起做`与运算`，得到数字的最后一个bit位 判断这个数字是否为0
                    if ((num & 1) == 0) {
                        // 如果为0
                    } else {
                        // 如果为1
                        SignInfo.add(whichDay);
                        count++;
                    }
                    whichDay--;
                    // 无符号右移
                    num >>>= 1;
                }

                map.clear();
                map.put("SignCount", String.valueOf(count));
                map.put("SignInfo", String.valueOf(SignInfo));
            }
        }
        return new DataResponse("200", map);
    }

    @Override
    public DataResponse setWordsTime(@RequestBody String request) {
        DataRequest requestBody = com.lmj.utils.RequestBody.getRequestBody(request);
        String userStatusId = requestBody.getString("userStatusId");
        String totalWords = requestBody.getString("totalWords");
//        String totalTime = requestBody.getString("totalTime");

        UserStatus userStatus = userStatusMapper.selectById(Long.parseLong(userStatusId));

        userStatus.setTotalWords(Integer.parseInt(totalWords));
//        userStatus.setTotalTime(Integer.parseInt(totalTime));
        userStatusMapper.updateById(userStatus);

        map.clear();
        map.put("userStatusId", userStatusId);

        return new DataResponse("200", map);
    }

}
